package com.avcompris.util;

import static com.avcompris.util.ExceptionUtils.nonNullArgument;
import static com.avcompris.util.log.LogUtils.logErrorFormat;
import static org.apache.log4j.Logger.getLogger;

import java.io.InputStream;

import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;

import org.apache.log4j.Logger;

import com.avcompris.common.annotation.Nullable;

/**
 * implementation of {@link URIResolver} that points to the resources in "
 * <tt>/xslt/*</tt>" for XSLT imports.
 * 
 * @author David Andriana Copyright Avantage Compris SARL 2008-2009 ©
 */
public class XsltResourceURIResolver implements URIResolver {

	/**
	 * the logger to use;
	 */
	private static final Logger logger = getLogger(XsltResourceURIResolver.class);

	/**
	 * the {@link ClassLoader} to use for resource resolution.
	 */
	private final ClassLoader classLoader;

	/**
	 * constructor.
	 * 
	 * @param classLoader the {@link ClassLoader} to use for resource resolution
	 */
	public XsltResourceURIResolver(final ClassLoader classLoader) {

		nonNullArgument(classLoader, "classLoader");

		this.classLoader = classLoader;
	}

	/**
	 * constructor.
	 * 
	 * @param c a class contained in the {@link ClassLoader} to use for resource
	 *            resolution
	 */
	public XsltResourceURIResolver(final Class<?> c) {

		nonNullArgument(c, "class");

		this.classLoader = c.getClassLoader();
	}

	/**
	 * resolve an URI.
	 * 
	 * @param href the URI to resolve
	 * @param base the base URI (typically, <tt>null</tt> in the case of a
	 *            resource, but it can also be the original file's path in the
	 *            File System)
	 * @return the {@link Source} to import
	 */
	@Override
	public final Source resolve(final String href, @Nullable
	final String base) throws TransformerException {

		nonNullArgument(href, "href");

		if (!href.startsWith("/")) {
			throw new TransformerException("Href should start with \"/\": \""
					+ href + "\"");
		}

		final String path = "xslt" + href;

		final InputStream is = classLoader.getResourceAsStream(path);

		if (is == null) {

			logErrorFormat(logger, "Cannot load resource: \"%s\"", path);

			throw new TransformerException("Cannot load resource: \"" + path
					+ "\"");
		}

		return new StreamSource(is);
	}
}
